﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace WinFormsApp_MultiThread
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }


        #region 异步执行程序1

        //参考文章：http://www.cnblogs.com/pengstone/archive/2012/12/25.html
        /// <summary>
        /// 单独执行一个异步方法的简洁调用：(这种方式的回调函数的返回值可以用全局变量来接收..)
        /// </summary>
        private void AsyncMethod()
        {
            //定义一个与方法声明相同的委托来异步执行方法
            Func<int> delegate1 = () =>
            {
                //为方便调试看到效果,增加一个耗时的计算任务
                int sum = 0;
                for (int i = 0; i < 10000; i++)
                {
                    sum += i;
                }
                return sum;
            };

            delegate1.BeginInvoke(state =>
            {
                int sum = delegate1.EndInvoke(state);
                Console.WriteLine("使用委托异步执行方法，结果为：{0}", sum.ToString());
                for (int i = 0; i < 10000; i++)
                {
                    //为方便调试看到效果,增加一个耗时的计算任务
                }
            }, null);
        }

        #endregion

        #region 异步执行程序2

        public void btnExecAsync(object sender, EventArgs e)
        {
            //给委托赋值
            _delegateMethod1 = DoSomeThing;// new DelegateMethod(DoSomeThing);
            //异步执行委托,这里把委托本身作为asyncState对象传进去，在回调函数中需要使用委托的EndInvoke来获得结果
            _delegateMethod1.BeginInvoke(DoneCallback, _delegateMethod1);
            for (int i = 0; i < 10000; i++)
            {
                //A部分
                //A和B部分是并行执行的,相互之间无影响
            }
        }

        private DelegateMethod _delegateMethod1;//实例化委托
        public delegate bool DelegateMethod();//声明委托

        /// <summary>
        /// 委托回调函数
        /// </summary>
        void DoneCallback(IAsyncResult asyncResult)
        {
            //到这儿委托(B部分)已经在异步线程中执行完毕

            //委托执行的异常会在EndInvoke时抛出来 
            try
            {
                //使用BeginInvoke时传入委托的EndInvoke获得执行结果，这时候执行结果已经出来了，有异常的话也在这儿抛出来
                bool result = _delegateMethod1.EndInvoke(asyncResult);
            }
            catch (OutOfMemoryException) // (OverflowException)
            {
                //MessageBox.Show("异常!")
            }
        }

        /// <summary>
        /// 委托方法 异步执行
        /// </summary> 
        bool DoSomeThing()
        {
            //B部分  委托在另一个线程中开始执行 
            for (int i = 0; i < 10000; i++)
            {

            }
            return true;
        }

        #endregion

        #region 异步执行程序3
        public void AsyncMethod3()
        {
            ThreadStart threadStarter =
                () =>
                {
                    for (int i = 0; i < 10000; i++)
                    {
                        //为方便调试看到效果,增加一个耗时的计算任务
                    }

                };
            var thread = new Thread(threadStarter);
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();
        }
        #endregion

        //点击button1时，开始一个新线程，新线程中有一个方法
        public delegate void SetTextDelegate(int text);

        private void button1_Click(object sender, EventArgs e)
        {
            Thread th = new Thread(new ThreadStart(SetText));
            th.Start();
        }
        private void SetText()
        {
            for (int a = 0; a < 1000000; a++)
            {
                if (textBox1.InvokeRequired)
                {
                    textBox1.Invoke(new SetTextDelegate(SetTextDo), a);
                }
            }
        }

        public void SetTextDo(int i)
        {
            textBox1.Text = i.ToString();
        }

    }
}
